#include "PlayManager.h"
#include "Object/PlaySelectGhostObj.h"
#include "Object/PlayAdjustGhostObj.h"
#include "Object/ResultGhostObj.h"
#include "../Level/LevelManager.h"
#include <cocostudio/cocostudio.h>
#include "Layers/PlayGhostLayer.h"
#include "Layers/PlayResultLayer.h"
#include "../../Player/PlayerInfo.h"
#include "../../Data/LevelData.h"
#include "../../Data/GameData.h"
#include "../../Support/GameSupport.h"
using namespace cocostudio;
EGameStatus PlayManager::m_EGameStatus = EGameStatus::None;
cocos2d::Scene* PlayManager::createScene()
{
	auto scene = Scene::create();

	auto layer = PlayManager::create();
	layer->initialize();
	scene->addChild(layer);
	return scene;
}

// on "init" you need to initialize your instance
bool PlayManager::init()
{
	//////////////////////////////
	// 1. super init first
	if (!Layer::init())
	{
		return false;
	}

	setKeypadEnabled(true);

	m_screenSize = Director::getInstance()->getVisibleSize();

	return true;
}

void PlayManager::initBackground()
{
	Sprite* background = nullptr;
	switch (m_ELevelMode) {
	case Easy:
		background = Sprite::create("bg_easy.png");
		break;
	case Normal:
		background = Sprite::create("bg_normal.png");
		break;
	case Hard:
		background = Sprite::create("bg_hard.png");
		break;
	default:
		break;
	}
	kSpriteHeight = 250;
	kSpriteWidth = 200;

	float scaleX = m_screenSize.width / background->getContentSize().width;
	float scaleY = m_screenSize.height / background->getContentSize().height;
	background->setScale(scaleX, scaleY);
	//  cocos2d::Vector<Node*> list = node->getChildren();
	background->setAnchorPoint(Vec2(0.5f, 0.5f));
	background->setPosition(Vec2(m_screenSize.width / 2, m_screenSize.height / 2));
	this->addChild(background);
}

void PlayManager::initialize()
{
	m_ELevelMode = LevelManager::m_ELevelMode;

	this->removeAllChildren();
	initBackground();
	initLayer();

	switch (m_ELevelMode)
	{
	case ELevelMode::Easy:
		m_EModeType = GameData::getInstance()->easyMode.at(LevelManager::currID).Type;
		break;
	case ELevelMode::Normal:
		m_EModeType = GameData::getInstance()->normalMode.at(LevelManager::currID).Type;
		break;
	case ELevelMode::Hard:
		m_EModeType = GameData::getInstance()->hardMode.at(LevelManager::currID).Type;
		break;
	}

	if (m_EModeType == EModeType::ADJUST)
	{
		m_Clound = static_cast<Sprite*>(m_PlayAdjustLayer->getChildByName(std::string(GameSupport::getTextForEnumPlayComponent(EPlayComponent::Clound))));
		m_Clound->setAnchorPoint(Vec2(0.5f,0.5f));
		Button* btnSettings = static_cast<Button*>(m_PlayAdjustLayer->getChildByName(std::string(GameSupport::getTextForEnumPlayComponent(EPlayComponent::btnSettings))));

		 m_loadingBar = static_cast<LoadingBar*>(m_PlayAdjustLayer->getChildByName(
			std::string(GameSupport::getTextForEnumPlayComponent(EPlayComponent::TimeBarBG)))->getChildByName(
			std::string(GameSupport::getTextForEnumPlayComponent(EPlayComponent::TimeBarFG))));

		 auto func = CallFunc::create(std::bind(&PlayManager::calculateTimePlay, this, m_loadingBar));
		 m_loadingBar->runAction(RepeatForever::create(Sequence::create(DelayTime::create(1.0f), func, NULL)));

		OpenPlayAdjustLayer();
	}
	else if (m_EModeType == EModeType::SELECT)
	{
		m_Clound = static_cast<Sprite*>(m_PlaySelectLayer->getChildByName(std::string(GameSupport::getTextForEnumPlayComponent(EPlayComponent::Clound))));
		m_Clound->setAnchorPoint(Vec2(0.5f, 0.5f));
		Button* btnSettings = static_cast<Button*>(m_PlaySelectLayer->getChildByName(std::string(GameSupport::getTextForEnumPlayComponent(EPlayComponent::btnSettings))));

		m_loadingBar = static_cast<LoadingBar*>(m_PlaySelectLayer->getChildByName(
			std::string(GameSupport::getTextForEnumPlayComponent(EPlayComponent::TimeBarBG)))->getChildByName(
			std::string(GameSupport::getTextForEnumPlayComponent(EPlayComponent::TimeBarFG))));
		
		auto func = CallFunc::create(std::bind(&PlayManager::calculateTimePlay, this, m_loadingBar));
		m_loadingBar->runAction(RepeatForever::create(Sequence::create(DelayTime::create(1.0f), func, NULL)));

		OpenPlaySelectLayer();
	}
}

void PlayManager::initLayer()
{
	auto node = CSLoader::getInstance()->createNode("GameScene.csb");
	float scale = m_screenSize.height / node->getContentSize().height;
	kScale = scale;
	node->setScale(scale);

	m_PlaySelectLayer = node->getChildByName(std::string(GameSupport::getTextForEnumPlayLayer(EPlayLayerTag::GamePlaySelectLayer)));
	
    m_PlayAdjustLayer = node->getChildByName(std::string(GameSupport::getTextForEnumPlayLayer(EPlayLayerTag::GamePlayAdjustLayer)));
    Button* btnIncrease = static_cast<Button*>(m_PlayAdjustLayer->getChildByName(std::string(GameSupport::getTextForEnumPlayComponent(EPlayComponent::btnIncrease))));
    Button* btnShink = static_cast<Button*>(m_PlayAdjustLayer->getChildByName(std::string(GameSupport::getTextForEnumPlayComponent(EPlayComponent::btnShink))));
    
    btnIncrease->setTitleText("+1");
    btnShink->setTitleText("-1");
    btnIncrease->setTitleFontSize(btnIncrease->getContentSize().width/3);
     btnShink->setTitleFontSize(btnShink->getContentSize().width/3);
    btnIncrease->addClickEventListener(CC_CALLBACK_1(PlayManager::AdjustGhost, this));
    btnShink->addClickEventListener(CC_CALLBACK_1(PlayManager::AdjustGhost, this));
    
    
	m_CongratulationsLayer = node->getChildByName(std::string(GameSupport::getTextForEnumPlayLayer(EPlayLayerTag::CongratulationsLayer)));
	//Button* btnReplay = static_cast<Button*>(m_CongratulationsLayer->getChildByTag(ECongraLayerTag::btnReplay));
	//btnReplay->addClickEventListener(CC_CALLBACK_0(PlayManager::initialize, this));
	//Button* btnNext = static_cast<Button*>(m_CongratulationsLayer->getChildByTag(ECongraLayerTag::btnNext));
	//btnNext->addClickEventListener(CC_CALLBACK_0(PlayManager::ReturnLevelScene, this));


	m_ResultLayer = node->getChildByName(std::string(GameSupport::getTextForEnumPlayLayer(EPlayLayerTag::ResultLayer)));

	m_CongratulationsLayer->setVisible(false);
	m_ResultLayer->setVisible(false);
	node->setAnchorPoint(Vec2(0.5f, 0.5f));

	node->setPosition(m_screenSize.width / 2, m_screenSize.height / 2);

	this->addChild(node);
}

void PlayManager::OpenPlaySelectLayer()
{
	m_PlaySelectLayer->setVisible(true);
	m_PlayAdjustLayer->setVisible(false);
	m_CongratulationsLayer->setVisible(false);
	m_ResultLayer->setVisible(false);
	initGame();
	initGhost();
	m_EGameStatus = EGameStatus::None;
	GamePlayConfig::GetInstance()->m_selectNumber = -1;
	m_currStar = 3;
	this->scheduleUpdate();
}

void PlayManager::OpenPlayAdjustLayer()
{
	m_PlayAdjustLayer->setVisible(true);
	m_PlaySelectLayer->setVisible(false);
	m_CongratulationsLayer->setVisible(false);
	m_ResultLayer->setVisible(false);
	initGame();
	initGhost();
	m_EGameStatus = EGameStatus::None;
	GamePlayConfig::GetInstance()->m_selectNumber = -1;
	m_currStar = 3;
	this->scheduleUpdate();
}

void PlayManager::initGhost()
{
	//ghostPanel->setPosition(-m_screenSize.width/2,m_screenSize.height/2);
	//ghostPanel->setPosition(0,m_screenSize.height/2);

	//ghostPanel->setTag(100);
	// m_PlayLayer->setPosition(-m_screenSize.width/5,m_PlayLayer->getPosition().y);

	PlayGhostLayer* layer = new PlayGhostLayer(m_screenSize);
	layer->setPosition(Vec2::ZERO);
	layer->autorelease();
	this->addChild(layer);

	if (m_EModeType == EModeType::ADJUST)
	{
	
        auto str = cocos2d::String::createWithFormat("%s%d", GameSupport::getTextForEnumPlayLayer(EPlayLayerTag::nodeGhost_),
                                                     GameData::getInstance()->easyMode.at(LevelManager::currID).NumGhostStart)->getCString();
        m_nodeGhostPlay = m_PlayAdjustLayer->getChildByName("nodeNormal")->getChildByName(str);
        CCLOG("%d",(int)m_nodeGhostPlay->getChildrenCount());
		layer->initalize(m_nodeGhostPlay);
	}
	else
	{
		auto str = cocos2d::String::createWithFormat("%s%d", GameSupport::getTextForEnumPlayLayer(EPlayLayerTag::nodeGhost_),
			GameData::getInstance()->easyMode.at(LevelManager::currID).NumGhostStart)->getCString();
		m_nodeGhostPlay = m_PlaySelectLayer->getChildByName("nodeNormal")->getChildByName(str);
		switch (LevelManager::m_ELevelMode)
		{
		case ELevelMode::Easy :
			layer->initalize(m_nodeGhostPlay, GameData::getInstance()->easyMode.at(LevelManager::currID).listExpression.begin()->Answer);
			break;
		case ELevelMode::Normal:
			layer->initalize(m_nodeGhostPlay, GameData::getInstance()->normalMode.at(LevelManager::currID).listExpression.begin()->Answer);
			break;
		case ELevelMode::Hard:
			layer->initalize(m_nodeGhostPlay, GameData::getInstance()->hardMode.at(LevelManager::currID).listExpression.begin()->Answer);
			break;
		}
		
	}

	

}

void PlayManager::initGame()
{
	char s[100];

	std::vector<Expression> listExpression;
	
    
	switch (LevelManager::m_ELevelMode)
	{
	case ELevelMode::Easy:
		listExpression = GameData::getInstance()->easyMode.at(LevelManager::currID).listExpression;
		break;
	case ELevelMode::Normal:
		listExpression = GameData::getInstance()->normalMode.at(LevelManager::currID).listExpression;
		break;
	case ELevelMode::Hard:
		listExpression = GameData::getInstance()->hardMode.at(LevelManager::currID).listExpression;
		break;
    }

	sprintf(s, "%s", listExpression.begin()->Question);
	GamePlayConfig::GetInstance()->m_hiddenNumber = listExpression.begin()->Answer;

	auto label = LabelTTF::create(s, "Arial", m_Clound->getContentSize().height*kScale / 3);
	label->setColor(Color3B::BLACK);
	label->setTag(EPlayComponent::Equation);
	label->setPosition(m_Clound->getContentSize().width / 2, m_Clound->getContentSize().height / 3);
    
	m_Clound->addChild(label);
}
void PlayManager::calculateTimePlay(Ref* pSender)
{
	
	m_loadingBar->setPercent(m_loadingBar->getPercent() - 1);
	m_currStar = m_loadingBar->getPercent() / 33;
}

void PlayManager::update(float dt)
{
    if(m_EModeType == EModeType::SELECT)
    {
	if (GamePlayConfig::GetInstance()->m_selectNumber != -1)
	{
		m_EGameStatus = GamePlayConfig::GetInstance()->CompareResult() ? EGameStatus::Correct : EGameStatus::Fail;
	}
	if (m_EGameStatus == EGameStatus::Correct || m_EGameStatus == EGameStatus::Fail)
	{
		this->unscheduleUpdate();
		OpenResultLayer();
	}
	else if (m_EGameStatus == EGameStatus::None)
	{
		if (m_loadingBar->getPercent() == 0)
		{
			m_EGameStatus = EGameStatus::Fail;
		}
	}
    }
    
}

void PlayManager::OpenResultLayer()
{
	m_PlaySelectLayer->setVisible(false);
	m_PlayAdjustLayer->setVisible(false);
	m_CongratulationsLayer->setVisible(false);

	initResult();
	m_ResultLayer->setVisible(true);

	auto func = CallFuncN::create(CC_CALLBACK_0(PlayManager::OpenCongratulationsLayer, this));
	m_ResultLayer->runAction(Sequence::create(DelayTime::create(3.0f), func, NULL));
}

void PlayManager::initResult()
{
	LabelTTF* label = (LabelTTF*)m_Clound->getChildByTag(EPlayComponent::Equation);
	std::string equation = label->getString();
	PlayResultLayer* layer = new PlayResultLayer(m_screenSize);
	layer->setPosition(Vec2::ZERO);
	//layer->setTag(EPlayLayerTag::DisplayResult);
	layer->autorelease();
	this->addChild(layer);

	layer->initalize(equation, m_EGameStatus);

}

void PlayManager::OpenCongratulationsLayer()
{
	m_ResultLayer->setVisible(false);
	//this->getChildByTag(EPlayLayerTag::DisplayResult)->removeFromParent();
	initCongratulations();
	m_CongratulationsLayer->setVisible(true);
}

void PlayManager::initCongratulations()
{
	if (m_currStar < 2)
	{
		Sprite* star3 = static_cast<Sprite*>(m_CongratulationsLayer->getChildByTag(ECongraLayerTag::sprStar3));
		star3->setVisible(false);
	}
	if (m_currStar < 1)
	{
		Sprite* star2 = static_cast<Sprite*>(m_CongratulationsLayer->getChildByTag(ECongraLayerTag::sprStar2));
		star2->setVisible(false);

	}
	if (m_currStar < 0)
	{
		Sprite* star2 = static_cast<Sprite*>(m_CongratulationsLayer->getChildByTag(ECongraLayerTag::sprStar2));
		star2->setVisible(false);

	}
	LabelTTF* label = (LabelTTF*)m_Clound->getChildByTag(EPlayComponent::Equation);
	std::string equation = label->getString();
	equation.replace(equation.find("?"), 1, String::createWithFormat("%d", GamePlayConfig::GetInstance()->m_selectNumber)->getCString());

	LabelTTF* newLabel = LabelTTF::create(equation, "Arial", 25);
	newLabel->setColor(Color3B::WHITE);

	//   newLabel->setScale(kScale);

	Sprite* sumbaryBox = (Sprite*)m_CongratulationsLayer->getChildByTag(ECongraLayerTag::SumaryBox);
	newLabel->setPosition(sumbaryBox->getContentSize().width / 2, sumbaryBox->getContentSize().height / 2);
	sumbaryBox->addChild(newLabel);


	//Save data play
	if (m_EGameStatus == EGameStatus::Correct)
	{
		PlayerInfo::getInstance()->level->setLevelEnable(LevelManager::m_ELevelMode, LevelManager::currID + 1, true);
	}
}

void PlayManager::AdjustGhost(cocos2d::Ref *pSender)
{
    Button* btn= (Button*)pSender;
    int numAdjust = stoi(btn->getTitleText());
    if(numAdjust > 0)
    {
        for(int i= 0,indexGhost = 1; i< numAdjust;i++)
        {
            int numRow= (int)m_nodeGhostPlay->getChildrenCount();
            for(int k= 0; k < numRow;k++)
            {
                Node* currRow = m_nodeGhostPlay->getChildByName(cocos2d::String::createWithFormat("%s%d","Row_",k + 1)->getCString());
                int numGhost =(int)currRow->getChildrenCount();
                for(int j= 0; j< numGhost;j++,indexGhost++)
                {
                     PlayAdjustGhostObj* ghost = (PlayAdjustGhostObj*)currRow->getChildByName(cocos2d::String::createWithFormat("%s%d","ghost_",indexGhost)->getCString())->getChildren().at(0);
                    if(!ghost->myGetVisible())
                    {
                        ghost->mySetVisible(true);
                        GamePlayConfig::GetInstance()->m_selectNumber++;
                        numAdjust--;
                        if(numAdjust == 0)
                            return;
                        break;
                    }
                   
                }
            }
            
        }
    }
    else
    {
        int num = abs(numAdjust);
        for(int i= 0,indexGhost = 1; i< num;i++)
        {
            int numRow= (int)m_nodeGhostPlay->getChildrenCount();
            for(int k= 0; k < numRow;k++)
            {
                Node* currRow = m_nodeGhostPlay->getChildByName(cocos2d::String::createWithFormat("%s%d","Row_",k + 1)->getCString());
                int numGhost =(int)currRow->getChildrenCount();
            for(int j= 0; j< numGhost;j++,indexGhost++)
            {

                PlayAdjustGhostObj* ghost = (PlayAdjustGhostObj*)currRow->getChildByName(cocos2d::String::createWithFormat("%s%d","ghost_",indexGhost)->getCString())->getChildren().at(0);
                if(ghost->myGetVisible())
                {
                    CCLOG("%s",ghost->getName().c_str());
                    ghost->mySetVisible(false);
                    GamePlayConfig::GetInstance()->m_selectNumber--;
                    num--;
                    if(num == 0)
                        return;
                    break;
                }
                
            }

        }
    }
    }
}

void PlayManager::ReturnLevelScene()
{
	Director::getInstance()->replaceScene(TransitionFade::create(0.5f, LevelManager::createScene(m_ELevelMode)));
}